#!/usr/bin/env node
'use strict'

const cac = require('cac')
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const shelljs = require('shelljs')
const webpack = require('webpack')
const childProcess = require('child_process')
const packageJson = require('./package.json')
const WebpackDevServer = require('webpack-dev-server')

const cli = cac('services')

const runChildProcess = (ProcessString) => {
  const _childProcess = childProcess.exec(ProcessString)
  _childProcess.stdout.on('data', console.info)
  _childProcess.stdout.on('error', console.info)
  _childProcess.stderr.on('data', console.info)
  _childProcess.stderr.on('error', console.info)
}

/** dev start */
cli.command('start').action(async (root, argv) => {
  process.env.NODE_ENV = 'development'
  let openElectronAPP = false
  const compiler = webpack(require('./webpack.config'))
  compiler.hooks &&
    compiler.hooks.done.tapAsync({ name: 'CompiledRenderProcessOnce' }, (compilation, callback) => {
      if (!openElectronAPP) {
        openElectronAPP = true
        runChildProcess('nodemon -e js,ts,tsx -w package.json -w index.js --exec electron . --inspect')
      }
      callback()
    })
  new WebpackDevServer(compiler, {
    hot: true,
    hotOnly: true,
    open: false,
    inline: true,
    noInfo: false,
    stats: 'errors-only',
    clientLogLevel: 'error',
    contentBase: path.join(__dirname, 'public'),
    host: '0.0.0.0',
    port: 9292,
    historyApiFallback: true,
    overlay: { errors: true, sockIntegration: 'wds' }
  }).listen(9292, (error) => {
    if (error) throw error
  })
})
cli.command('build').action(async (root, argv) => {
  process.env.NODE_ENV = 'production'
  const compiler = webpack(require('./webpack.config'))
  compiler.run((error, stats) => {
    compiler.close(() => {})
    if (error) throw error
    if (stats?.hasErrors()) {
      console.error(
        stats.toString({
          colors: true,
          errors: true,
          all: false
        })
      )
    }

    console.info(
      stats?.toString({
        all: false,
        colors: true,
        builtAt: true,
        timings: true,
        version: true,
        assets: true,
        errors: true,
        hash: true
      })
    )
    console.log(`......`)
  })
})

/** dev start */
cli.command('builder').action(async (root, argv) => {
  process.env.NODE_ENV = 'production'
  shelljs.rm('-rf', path.join(process.cwd(), 'output'))
  switch (process.platform) {
    case 'win32':
      shelljs.exec(`electron-builder --config ${path.join(process.cwd(), 'builder-config.js')} --win --ia32`)
      break
    case 'darwin':
      shelljs.exec(`electron-builder --config ${path.join(process.cwd(), 'builder-config.js')} --mac --x64`)
      break
    default: {
      console.error('环境不受支持，请联系开发者')
      process.exit(1)
    }
  }
})

cli.command('emitfile').action(async (root, argv) => {
  shelljs.rm('-rf', path.join(process.cwd(), 'public/library'))
  const { emitFile } = require('./package.json')
  for (const item of emitFile) {
    const fromPath = path.join(process.cwd(), 'node_modules', item.from)
    const toPath = path.join(process.cwd(), item.to)
    if (!fs.existsSync(toPath)) {
      fs.mkdirSync(toPath)
    }
    if (shelljs.cp('-R', fromPath, toPath).code !== 0) {
      shelljs.echo(chalk.red(`Error: copy file Error ${item.from} ===> ${item.to}`))
      shelljs.exit(1)
    } else {
      shelljs.echo(chalk.bgBlack('Copy File') + chalk.blue(` ${item.from} ===> ${item.to}`))
    }
  }
})

/** -h --help */
cli.help()
/** -v --version */
cli.version(packageJson.version)
/** 解析生效 */
cli.parse()
